package utils

import (
	"errors"
	"github.com/jinzhu/gorm"
	"sort"
	"strconv"
	"tizhi_front/model"
)

type CourseRecommend struct {
	LabelId int64
	Level   string
	Sex     string
	Grade   string
}
type CourseRecommendList []CourseRecommend

func (c CourseRecommendList) Len() int {
	return len(c)
}
func (c CourseRecommendList) Less(i, j int) bool {
	return c[i].LabelId < c[j].LabelId
}
func (c CourseRecommendList) Swap(i, j int) {
	c[i], c[j] = c[j], c[i]
}
func GetCourseList(uid int64, labelId int64) (courses []model.Course0, err error) {
	student := model.Student9{}
	err = student.SelectById(uid)
	if err != nil {
		return
	}
	if student.Sex != 1 && student.Sex != 2 {
		err = errors.New("unknown sex " + strconv.Itoa(int(student.Sex)))
		return
	}
	var courseRecommends []CourseRecommend
	err = getCourseItemTypeScore(uid, &student, &courseRecommends)
	if err != nil {
		return
	}
	sort.Sort(sort.Reverse(CourseRecommendList(courseRecommends)))
	if labelId == -1 {
		course := model.Course0{}
		for i := 0; i < len(courseRecommends); i++ {
			err = course.SelectByLabelIdLevelSexGrade(courseRecommends[i].LabelId, courseRecommends[i].Level, courseRecommends[i].Sex, courseRecommends[i].Grade)
			if err == gorm.ErrRecordNotFound {
				err = nil
				continue
			} else if err != nil {
				return
			}
			courses = append(courses, course)
		}
	} else {
		var isFind bool
		var courseRecommend CourseRecommend
		for i := 0; i < len(courseRecommends); i++ {
			if courseRecommends[i].LabelId == labelId {
				isFind = true
				courseRecommend = courseRecommends[i]
				break
			}
		}
		if !isFind {
			return
		} else {
			course := model.CourseE{}
			courses, err = course.SelectAllByLabelIdLevelSexGrade(courseRecommend.LabelId, courseRecommend.Level, courseRecommend.Sex, courseRecommend.Grade)
			return
		}
	}
	return
}

func getCourseItemTypeScore(uid int64, student *model.Student9, courseRecommends *[]CourseRecommend) (err error) {
	var scoreType byte
	if student.CurrentGrade == "11" || student.CurrentGrade == "12" {
		scoreType = 1
	} else if student.CurrentGrade == "13" || student.CurrentGrade == "14" {
		scoreType = 2
	} else if student.CurrentGrade == "15" || student.CurrentGrade == "16" {
		scoreType = 3
	} else if student.CurrentGrade == "21" || student.CurrentGrade == "22" || student.CurrentGrade == "23" || student.CurrentGrade == "31" || student.CurrentGrade == "32" || student.CurrentGrade == "33" {
		if student.Sex == 1 {
			scoreType = 4
		} else if student.Sex == 2 {
			scoreType = 5
		}
	} else {
		err = errors.New("unknown grade " + student.CurrentGrade)
		return
	}
	var typeScore map[int64][]float64
	switch scoreType {
	case 1:
		typeScore, err = getPrimary12TypeScore(uid)
		if err != nil {
			return
		}
		break
	case 2:
		typeScore, err = getPrimary34TypeScore(uid)
		if err != nil {
			return
		}
		break
	case 3:
		typeScore, err = getPrimary56TypeScore(uid)
		if err != nil {
			return
		}
		break
	case 4:
		typeScore, err = getHighMaleTypeScore(uid)
		if err != nil {
			return
		}
		break
	case 5:
		typeScore, err = getHighFemaleTypeScore(uid)
		if err != nil {
			return
		}
		break
	}
	getCourseRecommendCondition(&typeScore, student.Sex, student.CurrentGrade, courseRecommends)
	return
}

func getCourseRecommendCondition(typeScores *map[int64][]float64, sex byte, grade string, courseRecommends *[]CourseRecommend) {
	typeScore := make([]TypeScore, len(*typeScores))
	var i = 0
	for k, v := range *typeScores {
		isAllLack := true
		count := float64(0)
		for i := 0; i < len(v); i++ {
			if v[i] != -1 {
				isAllLack = false
			} else {
				v[i] = 0
			}
			count += v[i]
		}
		if isAllLack {
			typeScore[i].LabelId = k
			typeScore[i].Score = -1
		} else {
			typeScore[i].LabelId = k
			typeScore[i].Score = count / float64(len(v))
		}
		i++
	}
	sort.Sort(sort.Reverse(TypeScoreSlice(typeScore)))
	*courseRecommends = make([]CourseRecommend, len(typeScore))
	for i := 0; i < len(*courseRecommends); i++ {
		(*courseRecommends)[i].LabelId = typeScore[i].LabelId
		if typeScore[i].Score == -1 {
			(*courseRecommends)[i].Level = "level_0"
		} else if typeScore[i].Score < 60 {
			(*courseRecommends)[i].Level = "level_1"
		} else if typeScore[i].Score < 70 {
			(*courseRecommends)[i].Level = "level_2"
		} else if typeScore[i].Score < 80 {
			(*courseRecommends)[i].Level = "level_3"
		} else if typeScore[i].Score < 90 {
			(*courseRecommends)[i].Level = "level_4"
		} else if typeScore[i].Score < 100 {
			(*courseRecommends)[i].Level = "level_5"
		} else if typeScore[i].Score >= 100 {
			(*courseRecommends)[i].Level = "level_6"
		}
		if sex == 1 {
			(*courseRecommends)[i].Sex = "male"
		} else if sex == 2 {
			(*courseRecommends)[i].Sex = "female"
		}
		(*courseRecommends)[i].Grade = "grade_" + grade
	}
}
